package com.blue.utils;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Properties;

public class SshHelperUtils {

	public Logger log = (Logger) LoggerFactory.getLogger(getClass());
	
	private String host;// 服务器 连接ip
	private String username;// 用户名
	private String password;// 密码
	private int port = 22;// 端口号
	private ChannelExec sshChannel =null;
	private Session sshSession = null;
	
	
	public SshHelperUtils(){
		
	}
	
	public SshHelperUtils(String host, int port, String username, String password) {
		this.host = host;
		this.username = username;
		this.password = password;
		this.port = port;
	}

	public SshHelperUtils(String host, String username, String password) {
		this.host = host;
		this.username = username;
		this.password = password;
	}
	
	
	/**
	 * 通过SFTP连接服务器
	 */
	public boolean connect() {
		JSch jsch;
		boolean returnFlag=false;
		//SFtpReturnInfoVo sFtpReturnInfoVo = new SFtpReturnInfoVo();
		try {
			
			jsch = new JSch();
			jsch.getSession(username, host, port);
			sshSession = jsch.getSession(username, host, port);
			if (log.isInfoEnabled()) {
				log.info("Session created.");
			}
			sshSession.setPassword(password);
			Properties sshConfig = new Properties();
			//设置第一次登陆的时候提示，可选值：(ask | yes | no)
			sshConfig.put("StrictHostKeyChecking", "no");
			sshSession.setConfig(sshConfig);
			//设置登陆超时时间   
			sshSession.connect(30000);
			//sshSession.connect();
			if (log.isInfoEnabled()) {
				log.info("Session connected.");
			}
			//创建sftp通信通道
			/*sshChannel = (ChannelExec)sshSession.openChannel("exec");
			//sshChannel.connect(1000);
			sshChannel.connect();
			if (log.isInfoEnabled()) {
				log.info("Opening Channel.");
			}*/
			
			returnFlag=true;
			//sFtpReturnInfoVo.setRetrunFlag(true);
			return returnFlag;
			//return sFtpReturnInfoVo;
		} catch (Exception e) {
			e.printStackTrace();
			//sFtpReturnInfoVo.setRetrunFlag(false);
			//sFtpReturnInfoVo.setErrorMsg(getErrorInfoFromException(e));
			//return sFtpReturnInfoVo;
			return returnFlag;
		} finally {
			jsch = null;
		}
	}
	
	
	public String execSystemCmd(String cmdString){
		
		StringBuffer sb= new StringBuffer();
		
		try{
			
			sshChannel = (ChannelExec) sshSession.openChannel("exec");
			sshChannel.setCommand(cmdString); //执行命令
            //int exitStatus = sshChannel.getExitStatus(); //退出状态为-1，直到通道关闭
            //System.out.println(exitStatus);

            // 下面是得到输出的内容
            sshChannel.connect();
            InputStream in = sshChannel.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String buf = null;
            while ((buf = reader.readLine()) != null) {
                sb.append(buf+"\n");
            }
			
			System.out.println(sb.toString());
            return sb.toString();
		}catch(Exception ex){
			ex.printStackTrace();
			return sb.toString();
		}finally{
			sb=null;
		}
	}
	
	public String execSystemCmdByEnv(String cmdString,String parameterStr){
		
		StringBuffer sb= new StringBuffer();
		String baseInfo="";
		String homeInfoStr="";
		try{
			
			sshChannel = (ChannelExec) sshSession.openChannel("exec");
			sshChannel.setCommand(cmdString); //执行命令
            //int exitStatus = sshChannel.getExitStatus(); //退出状态为-1，直到通道关闭
            //System.out.println(exitStatus);

            // 下面是得到输出的内容
            sshChannel.connect();
            InputStream in = sshChannel.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String buf = null;
            while ((buf = reader.readLine()) != null) {
            	
            	//System.out.println(" env ::"+parameterStr+" === >> "+buf);
            	if(buf.indexOf("ORACLE_BASE=")>=0){
            		baseInfo=buf.replace("export", "").replace("ORACLE_BASE=", "").trim();
            	}
            	if(buf.indexOf(parameterStr)>=0){
            		homeInfoStr=buf.replace("export", "").replace("ORACLE_HOME=", "").trim();
            		//System.out.println(" ------------------ >>> homeInfoStr ::"+homeInfoStr);
            		if(homeInfoStr.startsWith("$ORACLE_BASE")){
            			homeInfoStr=homeInfoStr.replace("$ORACLE_BASE", baseInfo);
            		}/*else{
            			System.out.println(" -------+++----------- >>> homeInfoStr ::"+homeInfoStr);
            		}
            		System.out.println(" ------------------ >>> baseInfo ::"+baseInfo);*/
            		sb.append(homeInfoStr+"\n");
            	}
                
                
            }
			
			System.out.println(sb.toString());
            return sb.toString();
		}catch(Exception ex){
			ex.printStackTrace();
			return sb.toString();
		}finally{
			sb=null;
		}
	}
	
	
	/***
	 * ChannelShell channel = (ChannelShell) session.openChannel("shell");
		channel.connect();
		//从远程端到达的所有数据都能从这个流中读取到
		InputStream in = channel.getInputStream();
		//写入该流的所有数据都将发送到远程端。
		OutputStream outputStream = channel.getOutputStream();
		byte[] tmp=new byte[1024];
		while(true){
		  while(in.available()>0){
		    int i=in.read(tmp, 0, 1024);
		    if(i<0)break;
		    System.out.print(new String(tmp, 0, i));
		  }
		  if(channel.isClosed()){
		    if(in.available()>0) continue;
		    System.out.println("exit-status: "+channel.getExitStatus());
		    break;
		  }
		}
	 * @param cmdString
	 * @throws Exception
	 */
	
	public void execSystemCommand_test (String[] cmdString) throws Exception{
		
		BufferedReader in;
		String msg = null;
		ChannelShell channel = (ChannelShell) sshSession.openChannel("shell");
        channel.connect();
        
        InputStream inputStream = channel.getInputStream();//从远程端到达的所有数据都能从这个流中读取到
        OutputStream outputStream = channel.getOutputStream();//写入该流的所有数据都将发送到远程端。
        
        //好处就是不需要每次手动给字符串加\n
        PrintWriter printWriter = new PrintWriter(outputStream);//使用PrintWriter流的目的就是为了使用println这个方法
        
        String cmd = "cd /home/springBoot ";
        printWriter.println(cmd);
        
        String cmd2 = "ls";
        printWriter.println(cmd2);
        //outputStream.flush();
        
        
        String cmd3 = "./test.sh";
        printWriter.println(cmd3);
        
        printWriter.println("exit");//加上个就是为了，结束本次交互
        printWriter.flush();
        
        in = new BufferedReader(new InputStreamReader(inputStream));
        while((msg = in.readLine())!=null){
            System.out.println(msg);
        }
        
        in.close();
        
        if(channel !=null){
        	channel.disconnect();
        }
        
	}
	
	public String execSystemCmdByShellModule(String cmdString){
		BufferedReader in=null;
		String msg = null;
		PrintWriter printWriter = null;
		ChannelShell channelShell = null;
		
		String returnCmdStr="";
		try{
			channelShell = (ChannelShell) sshSession.openChannel("shell");
			channelShell.connect();
	        
	        InputStream inputStream = channelShell.getInputStream();//从远程端到达的所有数据都能从这个流中读取到
	        OutputStream outputStream = channelShell.getOutputStream();//写入该流的所有数据都将发送到远程端。
	        
	        //好处就是不需要每次手动给字符串加\n
	        printWriter = new PrintWriter(outputStream);//使用PrintWriter流的目的就是为了使用println这个方法
	        
	        printWriter.println(cmdString);
	        
	        printWriter.println("exit");//加上个就是为了，结束本次交互
	        printWriter.flush();
	        
	        in = new BufferedReader(new InputStreamReader(inputStream));
	        while((msg = in.readLine())!=null){
	        	if(msg.indexOf(cmdString)>=0 || msg.indexOf("$ORACLE _HOME")>=0){
	        		System.out.println(msg);
	        		returnCmdStr = in.readLine();
	        	}
	            
	        }
	        
	        in.close();
	        inputStream.close();
	        outputStream.close();
	        
	        return returnCmdStr;
		}catch(Exception ex){
			ex.printStackTrace();
			return returnCmdStr;
		}finally{
			
			msg=null;
			
			if(printWriter !=null){
				printWriter.close();
			}
			
			if(channelShell !=null){
				
				if (channelShell.isConnected()) {
					channelShell.disconnect();
					if (log.isInfoEnabled()) {
						log.info(" channelShell is closed already ...... ");
					}
				}
				//channelShell.disconnect();
	        }
		}
	}
	
	public void execSystemCommand (String[] cmdString){
		
		BufferedReader in=null;
		String msg = null;
		PrintWriter printWriter = null;
		ChannelShell channelShell = null;
		try{
			channelShell = (ChannelShell) sshSession.openChannel("shell");
			channelShell.connect();
	        
	        InputStream inputStream = channelShell.getInputStream();//从远程端到达的所有数据都能从这个流中读取到
	        OutputStream outputStream = channelShell.getOutputStream();//写入该流的所有数据都将发送到远程端。
	        
	        //好处就是不需要每次手动给字符串加\n
	        printWriter = new PrintWriter(outputStream);//使用PrintWriter流的目的就是为了使用println这个方法
	        
	        
	        for(String cmdStr:cmdString){
	        	printWriter.println(cmdStr);
	        }
	        /*String cmd = "cd /home/springBoot ";
	        printWriter.println(cmd);
	        
	        String cmd2 = "ls";
	        printWriter.println(cmd2);
	        //outputStream.flush();
	        
	        
	        String cmd3 = "./test.sh";
	        printWriter.println(cmd3);*/
	        
	        printWriter.println("exit");//加上个就是为了，结束本次交互
	        printWriter.flush();
	        
	        in = new BufferedReader(new InputStreamReader(inputStream));
	        while((msg = in.readLine())!=null){
	            System.out.println(msg);
	        }
	        
	        in.close();
	        inputStream.close();
	        outputStream.close();
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			
			
			msg=null;
			
			if(printWriter !=null){
				printWriter.close();
			}
			
			if(channelShell !=null){
				
				if (channelShell.isConnected()) {
					channelShell.disconnect();
					if (log.isInfoEnabled()) {
						log.info(" channelShell is closed already ...... ");
					}
				}
				//channelShell.disconnect();
	        }
		}
        
	}
	
	/**
	 * 关闭连接
	 */
	public void disconnect() {
		
		if (this.sshChannel != null) {
			if (this.sshChannel.isConnected()) {
				this.sshChannel.disconnect();
				if (log.isInfoEnabled()) {
					log.info(" sshChannel is closed already");
				}
			}
		}
		
		if (this.sshSession != null) {
			if (this.sshSession.isConnected()) {
				this.sshSession.disconnect();
				if (log.isInfoEnabled()) {
					log.info("sshSession is closed already");
				}
			}
		}
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	

	public ChannelExec getSshChannel() {
		return sshChannel;
	}

	public void setSshChannel(ChannelExec sshChannel) {
		this.sshChannel = sshChannel;
	}

	public Session getSshSession() {
		return sshSession;
	}

	public void setSshSession(Session sshSession) {
		this.sshSession = sshSession;
	}
	
	
	/** 测试 */
	public static void main(String[] args) {
		
		SshHelperUtils sshHelperUtils =null;
		
		try{
			
			sshHelperUtils = new SshHelperUtils("192.168.1.253", "cxf11", "BLUE");
			sshHelperUtils.connect();
			
			String[] cmdString=new String[1];
			
			cmdString[0]="echo $ORACLE_HOME";
			//cmdString[1]="ls";
			//cmdString[2]="./test.sh";
			
			sshHelperUtils.execSystemCmdByShellModule("echo $ORACLE_HOME");
			System.out.println("==========================");
			System.out.println("uname -a ::"+sshHelperUtils.execSystemCmd("uname -a"));
			System.out.println("echo $ORACLE_HOME ::"+sshHelperUtils.execSystemCmdByShellModule("echo $ORACLE_HOME"));
			//System.out.println(sshHelperUtils.execSystemCmd("echo $ORACLE_HOME"));
			System.out.println("==========================");
			sshHelperUtils.disconnect();
			
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			
		}
	}
	
}
